package com.ljw.gulimall.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ljw.common.constant.ProductConstant;
import com.ljw.gulimall.product.dao.AttrAttrgroupRelationDao;
import com.ljw.gulimall.product.dao.AttrGroupDao;
import com.ljw.gulimall.product.dao.CategoryDao;
import com.ljw.gulimall.product.entity.AttrAttrgroupRelationEntity;
import com.ljw.gulimall.product.entity.AttrGroupEntity;
import com.ljw.gulimall.product.entity.CategoryEntity;
import com.ljw.gulimall.product.service.AttrAttrgroupRelationService;
import com.ljw.gulimall.product.service.CategoryService;
import com.ljw.gulimall.product.vo.Attr;
import com.ljw.gulimall.product.vo.AttrGroupRelationVo;
import com.ljw.gulimall.product.vo.AttrResVo;
import com.ljw.gulimall.product.vo.AttrVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ljw.common.utils.PageUtils;
import com.ljw.common.utils.Query;

import com.ljw.gulimall.product.dao.AttrDao;
import com.ljw.gulimall.product.entity.AttrEntity;
import com.ljw.gulimall.product.service.AttrService;
import org.springframework.transaction.annotation.Transactional;


@Service("attrService")
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {

    @Autowired
    private AttrAttrgroupRelationService attrAttrgroupRelationService;

    @Autowired
    private AttrGroupDao attrGroupDao;

    @Autowired
    private CategoryDao categoryDao;

    @Autowired
    private AttrAttrgroupRelationDao relationDao;

    @Autowired
    private CategoryService categoryService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                new QueryWrapper<AttrEntity>()
        );

        return new PageUtils(page);
    }

    /**
     * 添加属性并设置其属性分组
     * @param attr
     */
    @Override
    @Transactional
    public void saveAttr(AttrVo attr) {
        //1、先保存属性信息
        AttrEntity attrEntity = new AttrEntity();
        BeanUtils.copyProperties(attr, attrEntity);
        baseMapper.insert(attrEntity);
        //2、如果是基本属性则需要保存属性对应的属性分组信息
        if (attr.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode() && attr.getAttrGroupId() != null){
            AttrAttrgroupRelationEntity attrAttrgroupRelationEntity = new AttrAttrgroupRelationEntity();
            attrAttrgroupRelationEntity.setAttrId(attrEntity.getAttrId());
            attrAttrgroupRelationEntity.setAttrGroupId(attr.getAttrGroupId());
            attrAttrgroupRelationService.save(attrAttrgroupRelationEntity);
        }
    }

    @Override
    public PageUtils queryBaseAttrPage(Map<String, Object> params, Long catelogId, String attrType) {

        //封装前端传过来的分类id，查询出该分类id的数据
        LambdaQueryWrapper<AttrEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AttrEntity::getAttrType, "base".equalsIgnoreCase(attrType) ? ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode() : ProductConstant.AttrEnum.ATTR_TYPE_SALE.getCode());
        if (catelogId != 0){
            wrapper.eq(AttrEntity::getCatelogId, catelogId);
        }

        //封装带条件的查询
        String key = (String) params.get("key");
        if (!StringUtils.isBlank(key)){
            wrapper.and(obj -> {
               wrapper.eq(AttrEntity::getAttrId, key).or().like(AttrEntity::getAttrName, key);
            });
        }
        //封装分页查询条件
        IPage<AttrEntity> page = new Query<AttrEntity>().getPage(params);
        baseMapper.selectPage(page, wrapper);

        //把分页查询结果封装成前面统一返回数据
        PageUtils pageUtils = new PageUtils(page);

        //由于表中没有分类的名字和属性分组的名字，因为要修改records中添加这两个属性
        List<AttrEntity> records = page.getRecords();
        List<AttrResVo> collect = records.stream().map(attrEntity -> {
            AttrResVo attrResVo = new AttrResVo();
            BeanUtils.copyProperties(attrEntity, attrResVo);
            //设置分类的名字
            CategoryEntity categoryEntity = categoryDao.selectById(attrEntity.getCatelogId());
            if (categoryEntity != null) {
                attrResVo.setCatelogName(categoryEntity.getName());
            }
            //如果是查询基础属性则设置属性分组的名字
            if ("base".equalsIgnoreCase(attrType)){
                LambdaQueryWrapper<AttrAttrgroupRelationEntity> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(AttrAttrgroupRelationEntity::getAttrId, attrEntity.getAttrId());
                AttrAttrgroupRelationEntity attrAttrgroupRelationEntity = relationDao.selectOne(queryWrapper);
                if (attrAttrgroupRelationEntity != null && attrAttrgroupRelationEntity.getAttrGroupId() != null) {
                    AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrAttrgroupRelationEntity.getAttrGroupId());
                    attrResVo.setGroupName(attrGroupEntity.getAttrGroupName());
                }
            }
            return attrResVo;
        }).collect(Collectors.toList());
        //修改list中的值
        pageUtils.setList(collect);
        return pageUtils;
    }

    @Override
    public AttrResVo getAttrInfo(Long attrId) {
        //1、查询出属性的基本值
        AttrEntity attrEntity = baseMapper.selectById(attrId);
        AttrResVo attr = new AttrResVo();
        BeanUtils.copyProperties(attrEntity, attr);

        if (attrEntity.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()){
            //2、查询属性id查询出关联表中属性分组信息
            LambdaQueryWrapper<AttrAttrgroupRelationEntity> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(AttrAttrgroupRelationEntity::getAttrId, attrEntity.getAttrId());
            AttrAttrgroupRelationEntity relationEntity = relationDao.selectOne(wrapper);
            if (relationEntity != null){
                //2.1、在返回结果中设置属性分组的id
                attr.setAttrGroupId(relationEntity.getAttrGroupId());
                AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(relationEntity.getAttrGroupId());

                if (attrGroupEntity != null){
                    //2.2、在返回结果中设置属性分组的名字
                    attr.setGroupName(attrGroupEntity.getAttrGroupName());
                }
            }
        }

        //3、设置分类的完整路径id
        Long[] catelogPath = categoryService.getCatelogPath(attrEntity.getCatelogId());
        attr.setCatelogPath(catelogPath);

        return attr;
    }

    @Override
    @Transactional
    public void updateAttr(AttrVo attr) {
        //1、修改属性的基本信息
        AttrEntity attrEntity = new AttrEntity();
        BeanUtils.copyProperties(attr, attrEntity);
        baseMapper.updateById(attrEntity);

        //如果属性为基本属性则需要修改关联表和属性分组信息
        if (attrEntity.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()){
            //2、修改属性和属性分组关联表的信息
            AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
            relationEntity.setAttrId(attr.getAttrId());
            relationEntity.setAttrGroupId(attr.getAttrGroupId());

            //3、修改的属性之前可能未设置属性分组，所以关联表中可能不存在数据，先判断关联表中是否存在该属性
            LambdaQueryWrapper<AttrAttrgroupRelationEntity> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(AttrAttrgroupRelationEntity::getAttrId, attr.getAttrId());
            AttrAttrgroupRelationEntity selectOne = relationDao.selectOne(wrapper);

            //4、如果查询出来不为空，说明之前已设置属性分组
            if (selectOne != null){
                relationDao.update(relationEntity, wrapper);
            }
            //5、为空则需要做添加操作
            else {
                relationDao.insert(relationEntity);
            }
        }
    }

    /**
     * 查询一个属性分组下所有的属性
     * @param attrGroupId
     * @return
     */
    @Override
    public List<AttrEntity> getRelationAttr(Long attrGroupId) {

        //1、查询出该属性分组下所有的属性的id
        LambdaQueryWrapper<AttrAttrgroupRelationEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AttrAttrgroupRelationEntity::getAttrGroupId, attrGroupId);
        List<AttrAttrgroupRelationEntity> entities = relationDao.selectList(wrapper);
        List<Long> collect = entities.stream().map(entity -> {
            return entity.getAttrId();
        }).collect(Collectors.toList());

        //2、查询出所有的属性
        List<AttrEntity> attrEntityList = new ArrayList<>();
        if (collect.size() > 0){
            attrEntityList = baseMapper.selectBatchIds(collect);
        }
        return attrEntityList;
    }

    @Override
    public void deleteRelation(AttrGroupRelationVo[] vos) {
        LambdaQueryWrapper<AttrAttrgroupRelationEntity> wrapper = new LambdaQueryWrapper<>();

        //封装批量删除
        for (int i = 0; i < vos.length; i++) {
            Long attrId = vos[i].getAttrId();
            Long attrGroupId = vos[i].getAttrGroupId();
            wrapper.or( obj -> {
                obj.eq(AttrAttrgroupRelationEntity::getAttrId, attrId);
                obj.eq(AttrAttrgroupRelationEntity::getAttrGroupId, attrGroupId);
            });
        }
        relationDao.delete(wrapper);
    }

    /**
     * 获取该属性分组下所有未关联的属性
     * @param attrGroupId
     * @param params
     * @return
     */
    @Override
    public PageUtils getNoRelationAttr(Long attrGroupId, Map<String, Object> params) {
        //1、当前属性分组只能关联与自己同分类的属性
        AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrGroupId);
        LambdaQueryWrapper<AttrEntity> attrWrapper = new LambdaQueryWrapper<>();
        attrWrapper.eq(AttrEntity::getCatelogId, attrGroupEntity.getCatelogId());
        List<AttrEntity> relationAttrs = baseMapper.selectList(attrWrapper);

        LambdaQueryWrapper<AttrAttrgroupRelationEntity> relationWrapper = new LambdaQueryWrapper<>();
        relationWrapper.eq(AttrAttrgroupRelationEntity::getAttrGroupId, attrGroupId);
        List<AttrAttrgroupRelationEntity> hadRelationAttrs = relationDao.selectList(relationWrapper);
        for (int i = 0; i < hadRelationAttrs.size(); i++) {
            for (int j = 0; j < relationAttrs.size(); j++) {
                if (hadRelationAttrs.get(i).getAttrId().equals(relationAttrs.get(j).getAttrId())){
                    relationAttrs.remove(relationAttrs.get(j));
                    break;
                }
            }
        }
        //2、当前属性分组只能关联未关联的属性
        LambdaQueryWrapper<AttrEntity> pageWrapper = new LambdaQueryWrapper<>();
        IPage<AttrEntity> page = new Query<AttrEntity>().getPage(params);
        if (relationAttrs.size() > 0){
            relationAttrs.forEach( attrEntity -> {
                pageWrapper.or( obj -> {
                    obj.eq(AttrEntity::getAttrId, attrEntity.getAttrId());
                });
            });
            baseMapper.selectPage(page, pageWrapper);
        }
        return new PageUtils(page);
    }

    @Override
    public List<Long> selectSearchAttrsIds(List<Long> attrIds) {
        LambdaQueryWrapper<AttrEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(AttrEntity::getAttrId);
        wrapper.in(AttrEntity::getAttrId, attrIds);
        wrapper.eq(AttrEntity::getSearchType,1);
        List<AttrEntity> attrEntityList = baseMapper.selectList(wrapper);
        List<Long> searchAttrIds = new ArrayList<>();
        for (AttrEntity attrEntity : attrEntityList) {
            searchAttrIds.add(attrEntity.getAttrId());
        }
        return searchAttrIds;
    }

}